﻿using System;
using __Able.Network.Utils;
using System.Collections.Generic;

namespace __Able.Network
{
    /// <summary>
    /// [包头长度]  |                [包头]                                |  [包体]  |  [包尾]
    /// --------------------------------------------------------------------------------------------
    ///             |  [序号] | [包ID] | [版本号] | [指令标记] | [模块名]  |          |   
    /// --------------------------------------------------------------------------------------------
    ///   (ushort)  |  
    ///   
    /// 
    /// [(ushort)包头长度][包体][(byte)包尾]
    /// 
    /// </summary>
    public abstract class CCUPacket : Packet
    {
        /// <summary>
        /// 包的描述性名称
        /// </summary>
        public override string PacketName
        {
            get
            {
                return string.Format("{0}_{1}.{2}.{3}.{4}_{5}", Module, Version[0], Version[1], Version[2], Version[3], Token);
            }
        }
        /// <summary>
        /// 用户对象
        /// </summary>
        public User User { get; protected set; }
        /// <summary>
        /// 模块
        /// </summary>
        /// <value></value>
        public string Module { get; protected set; }
        /// <summary>
        /// 版本
        /// </summary>
        /// <value></value>
        public byte[] Version { get; protected set; }
        /// <summary>
        /// 指令标记
        /// </summary>
        /// <value></value>
        public ushort Token { get; protected set; }
        /// <summary>
        /// 包ID
        /// </summary>
        public byte[] ID { get; protected set; }
        /// <summary>
        /// 包序号
        /// </summary>
        /// <value></value>
        public byte Sequence { get; protected set; }
        /// <summary>
        /// 包创建时间
        /// </summary>
        /// <value></value>
        public DateTime DateTime { get; protected set; }
        /// <summary>
        /// 获得包头长度
        /// </summary>
        public int HeaderLength { get; protected set; }
        /// <summary>
        /// 得到包体的字节数组
        /// </summary>
        /// <returns>包体字节数组</returns>
        public byte[] BodyDecrypted { get; protected set; }
        /// <summary>
        /// 构造一个指定参数的包
        /// </summary>
        /// <param name="source"></param>
        /// <param name="version"></param>
        /// <param name="command"></param>
        /// <param name="user"></param>
        public CCUPacket(string module, byte[] version, ushort token, byte sequence, byte[] id, User user)
        {
            this.User = user;
            this.Module = module;
            this.Token = token;
            this.Version = version;
            this.Sequence = sequence;
            this.ID = id;
            this.DateTime = DateTime.Now;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="user"></param>
        protected CCUPacket(ByteBuffer buf, User user)
        {
            this.User = user;
            // 获得加密包长度
            this.PacketLength = buf.GetUShort();

            // 得到加密包
            byte[] packet = buf.GetByteArray(this.PacketLength);
            // 解密
            byte[] dec = Decrypt(packet);
            if (dec == null)
            {
                throw new Exception("包内容解析出错，抛弃该包: " + ToString());
            }
            this.PacketLength = dec.Length;
            // 包装到ByteBuffer
            ByteBuffer tempBuf = new ByteBuffer(dec);
            try
            {
                // 解析包头
                ParseHeader(tempBuf);
                // 解析包体
                this.BodyDecrypted = ParseBody(tempBuf);
                // 解析包尾
                ParseTail(tempBuf);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message, e);
            }
            this.DateTime = DateTime.Now;
        }
        /// <summary>
        ///  加密包体
        /// </summary>
        /// <param name="b">未加密的字节数组</param>
        /// <returns>加密的包体</returns>
        protected virtual byte[] Encrypt(byte[] decryptPacket)
        {
            return decryptPacket;
        }
        /// <summary>
        /// 解密包体
        /// </summary>
        /// <param name="encryptPacket">包体字节数组</param>
        /// <returns>解密的包体字节数组</returns>
        protected virtual byte[] Decrypt(byte[] encryptPacket)
        {
                return encryptPacket;
        }
        /// <summary>
        /// 从buf中解析包头
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void ParseHeader(ByteBuffer buf);
        /// <summary>
        /// 从buf中解析包体
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract byte[] ParseBody(ByteBuffer buf);
        /// <summary>
        /// 从buf中解析包尾
        /// </summary>
        /// <param name="buf"></param>
        protected abstract byte ParseTail(ByteBuffer buf);
        /// <summary>
        /// 将包头部转化为字节流, 写入指定的ByteBuffer对象.
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void PutHead(ByteBuffer buf);
        /// <summary>
        /// 初始化包体
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void PutBody(ByteBuffer buf);
        /// <summary>
        /// 初始化包尾
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void PutTail(ByteBuffer buf);
    }
}
